<?php
/**
 * Upload文件上传控制器
 *
 * @version $Id: UploadController.class.php 357 2016-06-17 06:48:37Z chenhua $
 *
 */
namespace Sys\Controller;
use Todo\Controller\ApiController;
use Todo\Service\FileService;
use Todo\Util\Files;
use Todo\Util\PLUpload;
use Todo\Util\Uploader;

class UploadController extends ApiController{

    /**
	 * 默认上传配置
	 * @param array
	 */
    protected  $config = array(
        'mimes'         =>  array(), //允许上传的文件MiMe类型
        'maxSize'       =>  0, //上传的文件大小限制 (0-不做限制)
        'exts'          =>  array(), //允许上传的文件后缀
    	'rootPath'      =>  '../files/', //保存根路径
    	'um_save_path' => '/', //UM编辑器保存路径
        'hash'          =>  true, //是否生成hash编码
        'callback'      =>  false, //检测文件是否存在回调，如果存在返回文件信息数组
    );

    /*
	 * 文件默认保存路径
	 */
	protected  $_savePath;
	
    /**
     * 上传错误信息
     * @param string
     */
    protected  $error = ''; //上传错误信息
    
	public function _initialize()
    {	
		parent::_initialize();
    	/* 获取配置 */
        $this->config   =   array_merge($this->config, C('FILE_UPLOAD'));
        /* 调整配置，把字符串配置参数转换为数组 */
        if(!empty($this->config['mimes'])){
            if(is_string($this->mimes)) {
                $this->config['mimes'] = explode(',', $this->mimes);
            }
            $this->config['mimes'] = array_map('strtolower', $this->mimes);
        }
        if(!empty($this->config['exts'])){
            if (is_string($this->exts)){
                $this->config['exts'] = explode(',', $this->exts);
            }
            $this->config['exts'] = array_map('strtolower', $this->exts);
        }
    }
    
    public function test() {
        $vo['fileId'] = 6; //已经上传的文件ID
        $vo['thumbId'] = 1;
        $vo['coverId'] = 24;
        $this->assign('vo', $vo);
        $this->display();
    }

    /**
     * 上传Excel文件，不入库
     */
    public function excel(){
        $upload = new \Think\Upload();// 实例化上传类
        $upload->maxSize   =     3145728 ;// 设置附件上传大小
        $upload->exts      =     array('xls', 'xlsx');// 设置附件上传类型
        $upload->rootPath  =      C('FILE_UPLOAD.rootPath'); // 设置附件上传目录
        $upload->savePath  =      'excel/'; // 设置附件上传目录
        $upload->subName   =  array('date', 'Ym');
        $upload->hash   =  false;
        $info   =   $upload->upload(); // 上传文件
        if(!$info) {// 上传错误提示错误信息
            $this->apiError($upload->getError());
        }else{// 上传成功
            $this->apiData($info['file']['savepath'].$info['file']['savename']);
        }
    }


    /**
     * 上传Excel文件，不入库
     */
    public function image(){
        $upload = new \Think\Upload();// 实例化上传类
        $upload->maxSize   =     1048576 * 5 ;// 设置附件上传大小
        $upload->exts      =     explode(',', C('FILE_UPLOAD.image_exts'));// 设置附件上传类型
        $upload->rootPath  =      C('FILE_UPLOAD.rootPath'); // 设置附件上传目录
        $upload->savePath  =      'images/'; // 设置附件上传目录
        $upload->subName   =  array('date', 'Ym');
        $upload->hash   =  false;
        $info   =   $upload->upload(); // 上传文件
        if(!$info) {// 上传错误提示错误信息
            $this->apiError($upload->getError());
        }else{// 上传成功
            $this->apiData($info['file']['savepath'].$info['file']['savename']);
        }
    }
    
    /**
     * 文件上传
     */
    public function plsave(){
        $config = array(
            'autoSave' => true,
            'status'=>I('get.status',-1,'intval'),
            'rootPath' => $this->config['rootPath']
        );
        $PLUpload = new PLUpload($config);
        $PLUpload->upload(date('Y/m'));
    }

    
    /**
     * 头像上传接口
     */
    public function avatar(){
        $terminalid = get_terminalId();
        $userId = get_uid();
        $savePath = $this->config['avatarFolder'].'/'.$terminalid.'/'.$userId;
        $config = array(
            'autoSave' => false,
            'type' => 'avatar',
        );
        $PLUpload = new PLUpload($config);
        $PLUpload->upload($savePath);
    }

    /**
     * UEditor编辑器上传接口
     */
    public function ueditor(){
        $action = I('get.action', '', 'trim');
        $ueditorConfig = json_decode(preg_replace("/\/\*[\s\S]+?\*\//", "", file_get_contents(APP_PATH."../data/ueditor.config.json")), true);

        switch ($action) {
            case 'config':
                die(json_encode($ueditorConfig));
                break;
            /* 上传图片 */
            case 'uploadimage':
                $config = array(
                    "pathFormat" => $ueditorConfig['imagePathFormat'],
                    "maxSize" => $ueditorConfig['imageMaxSize'],
                    "allowFiles" => $ueditorConfig['imageAllowFiles']
                );
                $fieldName = $ueditorConfig['imageFieldName'];
                $this->_ueditorUpload($fieldName, $config);
                break;
                /* 上传涂鸦 */
            case 'uploadscrawl':
                $config = array(
                    "pathFormat" => $ueditorConfig['scrawlPathFormat'],
                    "maxSize" => $ueditorConfig['scrawlMaxSize'],
                    "allowFiles" => $ueditorConfig['scrawlAllowFiles'],
                    "oriName" => "scrawl.png"
                );
                $fieldName = $ueditorConfig['scrawlFieldName'];
                $this->_ueditorUpload($fieldName, $config, 'base64');
                break;
                /* 上传视频 */
            case 'uploadvideo':
                $config = array(
                    "pathFormat" => $ueditorConfig['videoPathFormat'],
                    "maxSize" => $ueditorConfig['videoMaxSize'],
                    "allowFiles" => $ueditorConfig['videoAllowFiles']
                );
                $fieldName = $ueditorConfig['videoFieldName'];
                $this->_ueditorUpload($fieldName, $config);
                break;
                /* 上传文件 */
            case 'uploadfile':
                $config = array(
                    "pathFormat" => $ueditorConfig['filePathFormat'],
                    "maxSize" => $ueditorConfig['fileMaxSize'],
                    "allowFiles" => $ueditorConfig['fileAllowFiles']
                );
                $fieldName = $ueditorConfig['fileFieldName'];
                $this->_ueditorUpload($fieldName, $config);
                break;
            /* 列出图片 */
            case 'listimage':
                $this->_ueditorList( $ueditorConfig['imageManagerAllowFiles'], $ueditorConfig['imageManagerListSize'], $ueditorConfig['imageManagerListPath']);
                break;
            /* 列出文件 */
            case 'listfile':
                $this->_ueditorList( $ueditorConfig['fileManagerAllowFiles'], $ueditorConfig['fileManagerListSize'], $ueditorConfig['fileManagerListPath']);
                break;

            /* 抓取远程文件 */
            case 'catchimage':
                $result = include("action_crawler.php");
                break;

            default:
                $result = json_encode(array(
                    'state'=> '请求地址出错'
                ));
                break;
        }

        /* 输出结果 */
        if (isset($_GET["callback"])) {
            if (preg_match("/^[\w_]+$/", $_GET["callback"])) {
                echo htmlspecialchars($_GET["callback"]) . '(' . $result . ')';
            } else {
                echo json_encode(array(
                    'state'=> 'callback参数不合法'
                ));
            }
        } else {
            echo $result;
        }

     
    }

    protected function _ueditorUpload($fieldName, $config, $base64='upload'){

        /* 生成上传实例对象并完成上传 */
        $up = new Uploader($fieldName, $config, $base64);

        $fileInfo = $up->getFileInfo();
        $fileData = FileService::getInstance()->saveUploadFile(".".$fileInfo['url'], $fileInfo['original']);
        $fileInfo['url'] = FileService::getInstance()->getUrlByPath($fileData['path']);
        die(json_encode($fileInfo));
    }
    
    protected function _ueditorList($allowFiles, $listSize, $path){

        $allowFiles = substr(str_replace(".", "|", join("", $allowFiles)), 1);

        /* 获取参数 */
        $size = isset($_GET['size']) ? htmlspecialchars($_GET['size']) : $listSize;
        $start = isset($_GET['start']) ? htmlspecialchars($_GET['start']) : 0;
        $end = $start + $size;

        /* 获取文件列表 */
        $files = Files::getfiles($path, $allowFiles);
        if (!count($files)) {
            return json_encode(array(
                "state" => "没有文件",
                "list" => array(),
                "start" => $start,
                "total" => count($files)
            ));
        }

        /* 获取指定范围的列表 */
        $len = count($files);
        for ($i = min($end, $len) - 1, $list = array(); $i < $len && $i >= 0 && $i >= $start; $i--){
            $files[$i]['url'] = FileService::getInstance()->getUrlByPath($files[$i]['path']);
            $list[] = $files[$i];
        }

        /* 返回数据 */
        $result = json_encode(array(
            "state" => "SUCCESS",
            "list" => $list,
            "start" => $start,
            "total" => count($files)
        ));

        die( $result);
    }

    /**
     * 上传图片接口
     * @param $save_url
     * @param $save_path
     */
    private function _upPic($save_url,$save_path,$folder){
        //定义允许上传的文件扩展名
        $ext_arr = array(
            'image' => array('gif', 'jpg', 'jpeg', 'png', 'bmp'),
        );
        //最大文件大小
        $max_size = 1000000;
        //PHP上传失败
        if (!empty($_FILES['imgFile']['error'])) {
            switch($_FILES['imgFile']['error']){
                case '1':
                    $error = '超过php.ini允许的大小。';
                    break;
                case '2':
                    $error = '超过表单允许的大小。';
                    break;
                case '3':
                    $error = '图片只有部分被上传。';
                    break;
                case '4':
                    $error = '请选择图片。';
                    break;
                case '6':
                    $error = '找不到临时目录。';
                    break;
                case '7':
                    $error = '写文件到硬盘出错。';
                    break;
                case '8':
                    $error = 'File upload stopped by extension。';
                    break;
                case '999':
                default:
                    $error = '未知错误。';
            }
            $this->alert($error);
        }

        //有上传文件时
        if (empty($_FILES) === false) {
            //原文件名
            $file_name = $_FILES['imgFile']['name'];
            //服务器上临时文件名
            $tmp_name = $_FILES['imgFile']['tmp_name'];
            //文件大小
            $file_size = $_FILES['imgFile']['size'];
            //检查文件名
            if (!$file_name) {
                $this->alert("请选择文件。");
            }
            //检查目录
            if (@is_dir($save_path) === false) {
                $this->alert("上传目录不存在。");
            }
            //检查目录写权限
            if (@is_writable($save_path) === false) {
                $this->alert("上传目录没有写权限。");
            }
            //检查是否已上传
            if (@is_uploaded_file($tmp_name) === false) {
                $this->alert("上传失败。");
            }
            //检查文件大小
            if ($file_size > $max_size) {
                $this->alert("上传文件大小超过限制。");
            }
            //获得文件扩展名
            $temp_arr = explode(".", $file_name);
            $file_ext = array_pop($temp_arr);
            $file_ext = trim($file_ext);
            $file_ext = strtolower($file_ext);
            $dir_name = 'image';
            //检查扩展名
            if (in_array($file_ext, $ext_arr[$dir_name]) === false) {
                $this->alert("上传文件扩展名是不允许的扩展名。\n只允许" . implode(",", $ext_arr[$dir_name]) . "格式。");
            }
            $save_path = $save_path.$folder;//定义保存目录
            $save_url  = $save_url.$folder;//定义返回目录
            if (!file_exists($save_path)) {
                @mkdir($save_path, 0775, true);
            }
            //新文件名
            $new_file_name = date("YmdHis") . '_' . rand(10000, 99999) . '.' . $file_ext;
            //移动文件
            $file_path = $save_path . $new_file_name;
            if (move_uploaded_file($tmp_name, $file_path) === false) {
                $this->alert("上传文件失败。");
            }
            @chmod($file_path, 0644);
            $file_url = $save_url . $new_file_name;

            header('Content-type: text/html; charset=UTF-8');
            echo json_encode(array('state' => 'SUCCESS', 'url' => $file_url,'type'=>$file_ext,'title' => $new_file_name,'original' => $file_name,'size'=>$file_size));
            exit;
        }
    }

    function alert($msg) {
        header('Content-type: text/html; charset=UTF-8');
        die(json_encode(array('state' => $msg)));
    }
}